﻿package {
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	import org.flixel.*;
			
	public class State extends FlxState	{
		internal var _player:Player;
		internal var _playerShot:FlxGroup;
		internal var _powerUp:FlxGroup;
		internal var _enemyShot:FlxGroup;
		internal var _enemyShip:FlxGroup;
		internal var _hud:HUD;
		private var _last_score:int;
		
		override public function create():void {
			/* load map */
		
			/* creates enemy fire */
			_enemyShot = new FlxGroup();
			add(_enemyShot);
			
			/* creates enemies */
			_enemyShip = new FlxGroup();
			add(_enemyShip);
			
			/* creates power group */
			_powerUp = new FlxGroup();
			add(_powerUp);			
			
			/* create hero fire */
			_playerShot = new FlxGroup();
			add(_playerShot);

			/* add our player */
			_player = new Player(0, 0);
			add(_player);			
			
			/* our hud */
			_hud = new HUD();
			add(_hud);
			
			_last_score = 0;

            FlxG.log("State:constructor");
		}
		
		override public function update():void {
			/* overlaps are helpers to test the collisions, and callback the treatment */
			FlxU.overlap(_playerShot, _enemyShip, setEnemyDamage);
			FlxU.overlap(_player, _powerUp, collectItems);
			
			/* if player is invecible do not test the collide with enemies ships and shots */
			if (!_player.isInvencible()) {
				FlxU.overlap(_player, _enemyShot, setHeroDamage);
				FlxU.overlap(_player, _enemyShip, setHeroAndEnemyCollide);				
			}
			
			/* prevent to update hud unnecessary */
			if (_player.getScore()!= _last_score) {
				_hud.updateScore(_player.getScore());
				_last_score = _player.getScore();
			}
			
			/* if player dies, then not exists */
			if (!_player.exists) {
				if (_player.getTries() >= 0) {
					FlxG.log("Recreate player");
					
					_player.setInvecible(true);
					_player.reset(_player.x, _player.y);
					_player.updateTries( -1);
					_hud.updateTries( -1);
				}else {
					/* fade out and call gameover state */
					FlxG.fade.start(0xff000000, 3, function():void{FlxG.state = new StateGameOver();});
				}
			}

			super.update();
		}
	
		private function setHeroAndEnemyCollide(Object1:FlxObject, Object2:FlxObject):void {
            FlxG.log("setHeroAndEnemyCollide");
			Object1.hurt(10);
			Object2.hurt(10);
			
            if(Object2.dead)
            {
               var e:Enemy = Object2 as Enemy;
               _player.updateScore(e.getPrize());
            }
		}

		private function setEnemyDamage(Object1:FlxObject, Object2:FlxObject):void {
            FlxG.log("setEnemyDamage");
			Object1.kill();
			Object2.hurt(Shot(Object1).getDamage());

            if(Object2.dead)
            {
              var e:Enemy = Object2 as Enemy;
              _player.updateScore(e.getPrize());
            }
		}
		
		private function setHeroDamage(Object1:FlxObject, Object2:FlxObject):void {
            FlxG.log("setHeroDamage");
			Object2.kill();
			Object1.hurt(Shot(Object2).getDamage());
		}
		
		private function collectItems(Object1:FlxObject, Object2:FlxObject):void {
			/* here we collect and get the prizes for each power up */
			if (Object2 is PowerUp) {
				switch(PowerUp(Object2).type) {
					case PowerUp.speedup:
						_player.upDefaultVelocity(20);
						break;
					case PowerUp.powerup:
						//TODO: must set weapons
						break;
					case PowerUp.lifeup:
						_player.upHealth(50);
						break;
					case PowerUp.scoreup:
						_player.updateScore(500);
						break;		
					case PowerUp.triesup:
						//TODO: tries
						break;								
				}
			}
			
			Object2.kill();
			FlxG.log("Collect a item " + PowerUp(Object2).getTypeName());
		}
		
		override public function destroy():void {
			/* at change the state destroy everything */
			_enemyShip.destroy();
			_enemyShot.destroy();
			_player.destroy();
			_playerShot.destroy();
			_powerUp.destroy();
			
			super.destroy();
		}
	}
}
